package com.enation.app.javashop.framework.interceptor;

import com.enation.app.javashop.framework.util.ObjectMapperUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.UUID;

/**
 *  前台服务请求拦截器
 */
@Aspect
@Component
public class ComposeRequestInterceptor {

    private static final String EDP = "execution(public * com..api.*.*Controller.*(..)) && (args(..))";

    /**
     * 日志记录
     */
    private final Logger log = LoggerFactory.getLogger(this.getClass());

    /**
     * 拦截
     */
    @Around(value=EDP)
    public Object interceptor(ProceedingJoinPoint point) throws Throwable {
        // 生成序列
        String serialId = UUID.randomUUID().toString().replace("-", "");

        // 打印请求日志
        this.printRequestLog(serialId, point.getArgs());

        // 业务方法处理
        Object response = this.businessWork(point);

        // 打印响应日志
        this.printResponseLog(serialId, response);

        return response;
    }


    // 业务方法处理
    private Object businessWork(ProceedingJoinPoint point) throws Throwable {
        Object response = null;
        try {
            response = point.proceed(point.getArgs());
        } catch (Throwable throwable) {
            log.error("ApiError", throwable);
            throw throwable;
        }
        return response;
    }


    /**
     * 打印请求日志
     */
    private void printRequestLog(String serialId, Object[] args){
        if(args != null && args.length != 0){
            Object paramBody = args[0];
            String bodyJsonStr = ObjectMapperUtils.prettyToJson(paramBody);
            log.info("序列id：" + serialId + "，Api请求报文：{}", "\r\n" + bodyJsonStr);
        }
    }


    /**
     * 打印响应日志
     */
    private void printResponseLog(String serialId, Object object){
        String bodyJsonStr = ObjectMapperUtils.prettyToJson(object);
        if(bodyJsonStr != null && bodyJsonStr.length() > 3000){
            log.info("序列id：" + serialId + "，Api响应报文：{}", "\r\nlog too big");
        }else{
            log.info("序列id：" + serialId + "，Api响应报文：{}", "\r\n" + bodyJsonStr);
        }
    }

}
